package com.kly.smartbi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kly.smartbi.common.ErrorCode;
import com.kly.smartbi.constant.CommonConstant;
import com.kly.smartbi.constant.UserContext;
import com.kly.smartbi.exception.ThrowUtils;
import com.kly.smartbi.mapper.QuestionMapper;
import com.kly.smartbi.model.dto.question.QuestionAddRequest;
import com.kly.smartbi.model.dto.question.QuestionQueryRequest;
import com.kly.smartbi.model.entity.Question;
import com.kly.smartbi.model.entity.QuestionTag;
import com.kly.smartbi.model.entity.Tag;
import com.kly.smartbi.model.entity.User;
import com.kly.smartbi.model.vo.QuestionVO;
import com.kly.smartbi.model.vo.TagVO;
import com.kly.smartbi.service.QuestionService;
import com.kly.smartbi.service.QuestionTagService;
import com.kly.smartbi.service.UserService;
import com.kly.smartbi.utils.BloomFilterUtil;
import org.redisson.api.RBloomFilter;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

import static com.kly.smartbi.constant.QuestionRedisConstant.QUESTION_GET_BLOOM_NAME;

/**
 * @author admin
 * @description 针对表【question(题目表)】的数据库操作Service实现
 * @createDate 2025-04-15 16:38:03
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question>
        implements QuestionService {

    @Resource
    private QuestionTagService questionTagService;

    @Resource
    private QuestionMapper questionMapper;

    @Resource
    private UserService userService;
    
    @Resource
    private BloomFilterUtil bloomFilterUtil;


    @Override
    public void validQuestion(Question question, boolean add) {
        ThrowUtils.throwIf(ObjUtil.isNull(question), ErrorCode.PARAMS_ERROR);
        //     校验是否合法
        String title = question.getTitle();
        String content = question.getContent();
        String answer = question.getAnswer();
        String judgeCase = question.getJudgeCase();
        String judgeConfig = question.getJudgeConfig();
        Long userId = question.getUserId();
        //     校验标题
        ThrowUtils.throwIf(StrUtil.isBlank(title) && title.length() < 50, ErrorCode.PARAMS_ERROR, "标题不能为空");
        //     校验内容
        ThrowUtils.throwIf(StrUtil.isBlank(content) && content.length() < 1000, ErrorCode.PARAMS_ERROR, "内容不能为空");
        //     校验答案
        ThrowUtils.throwIf(StrUtil.isBlank(answer) && answer.length() < 1000, ErrorCode.PARAMS_ERROR, "答案不能为空");

    }

    @Override
    public QueryWrapper<Question> getQueryWrapper(QuestionQueryRequest questionQueryRequest) {
        ThrowUtils.throwIf(ObjUtil.isNull(questionQueryRequest), ErrorCode.PARAMS_ERROR);
        Long id = questionQueryRequest.getId();
        String title = questionQueryRequest.getTitle();
        String content = questionQueryRequest.getContent();
        String answer = questionQueryRequest.getAnswer();
        Integer submitNum = questionQueryRequest.getSubmitNum();
        Integer acceptedNum = questionQueryRequest.getAcceptedNum();
        String judgeCase = questionQueryRequest.getJudgeCase();
        String judgeConfig = questionQueryRequest.getJudgeConfig();
        Integer thumbNum = questionQueryRequest.getThumbNum();
        Integer favourNum = questionQueryRequest.getFavourNum();
        Long userId = questionQueryRequest.getUserId();
        Date createTime = questionQueryRequest.getCreateTime();
        Date updateTime = questionQueryRequest.getUpdateTime();
        int current = questionQueryRequest.getCurrent();
        int pageSize = questionQueryRequest.getPageSize();
        String sortField = questionQueryRequest.getSortField();
        String sortOrder = questionQueryRequest.getSortOrder();
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(id != null, "id", id);
        queryWrapper.like(StrUtil.isNotBlank(title), "title", title);
        queryWrapper.like(StrUtil.isNotBlank(content), "content", content);
        queryWrapper.like(StrUtil.isNotBlank(answer), "answer", answer);
        queryWrapper.gt(submitNum != null, "submitNum", submitNum);
        queryWrapper.gt(acceptedNum != null, "acceptedNum", acceptedNum);
        queryWrapper.like(StrUtil.isNotBlank(judgeCase), "judgeCase", judgeCase);
        queryWrapper.like(StrUtil.isNotBlank(judgeConfig), "judgeConfig", judgeConfig);
        queryWrapper.gt(thumbNum != null, "thumbNum", thumbNum);
        queryWrapper.gt(favourNum != null, "favourNum", favourNum);
        queryWrapper.eq(userId != null, "userId", userId);
        queryWrapper.ge(createTime != null, "createTime", createTime);
        queryWrapper.le(updateTime != null, "updateTime", updateTime);
        queryWrapper.orderBy(StrUtil.isNotBlank(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }

    @Override
    public Page<Question> searchFromEs(QuestionQueryRequest questionQueryRequest) {
        return null;
    }

    @Override
    public QuestionVO getQuestionVO(Question question, HttpServletRequest request) {
        // 脱敏， 问题信息
        QuestionVO questionVO = BeanUtil.copyProperties(question, QuestionVO.class);
        // 补充标签信息 多表查询 自定义sql
        Long id = questionVO.getId();
        List<Tag> questionTagList = questionMapper.getQuestionTagList(id);
        List<TagVO> tags = questionTagList.stream().map(TagVO::objToVo).collect(Collectors.toList());
        questionVO.setTags(tags);
        // 设置用户信息
        User user = userService.getById(question.getUserId());
        questionVO.setUser(userService.getUserVO(user));
        return questionVO;
    }

    @Override
    public Page<QuestionVO> getQuestionVOPage(Page<Question> questionPage, HttpServletRequest request) {
        // 使用多表联查，自定义sql
        Page<QuestionVO> questionPageList = new Page<>(questionPage.getCurrent(), questionPage.getSize());
        List<Question> records = questionPage.getRecords();
        if (CollUtil.isEmpty(records)) {
            return questionPageList;
        }
        // 遍历QuestionVO
        List<QuestionVO> questionVOS = records.stream().map(QuestionVO::objToVo).collect(Collectors.toList());

        // 获取userId集合 userIdUserMap
        Set<Long> userIdList = records.stream().map(Question::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserMap = userService.listByIds(userIdList).stream().collect(Collectors.groupingBy(User::getId));
        questionVOS.forEach(questionVO -> {
            Long userId = questionVO.getUserId();
            User user = null;
            if (userIdUserMap.containsKey(userId)) {
                user = userIdUserMap.get(userId).get(0);
            }
            questionVO.setUser(userService.getUserVO(user));
            //     多表联查
            List<Tag> questionTagList = questionMapper.getQuestionTagList(questionVO.getId());
            List<TagVO> tags = questionTagList.stream().map(TagVO::objToVo).collect(Collectors.toList());
            questionVO.setTags(tags);
        });
        questionPageList.setRecords(questionVOS);
        return questionPageList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long addQuestion(QuestionAddRequest questionAddRequest) {
        Question question = new Question();
        BeanUtils.copyProperties(questionAddRequest, question);
        // 获取用户id
        Long userId = UserContext.getUser().getId();
        question.setUserId(userId);
        // 上传题目
        boolean result = this.save(question);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        // 保存标签
        List<Long> tagIds = questionAddRequest.getTagIds();
        List<QuestionTag> questionTagList = new ArrayList<>();
        if (CollUtil.isNotEmpty(tagIds)) {
            tagIds.forEach(tagId -> {
                QuestionTag questionTag = new QuestionTag();
                questionTag.setQuestionId(question.getId());
                questionTag.setTagId(tagId);
                questionTagList.add(questionTag);
            });
        }
        // 批量保存tags
        boolean saveResult = questionTagService.saveBatch(questionTagList);
        ThrowUtils.throwIf(!saveResult, ErrorCode.OPERATION_ERROR);
        // 添加到bloomFilter
        RBloomFilter<Object> bloomFilter = bloomFilterUtil.get(QUESTION_GET_BLOOM_NAME);
        bloomFilter.add(String.valueOf(question.getId()));
        return question.getId();
    }
}




